学习 Java 方法后的一些理解与总结
一个 Java 方法是为了执行某个操作的一些语句的组合,本质是一段代码片段。
1 | 方法定义在类体当中,在一个类当中可以定义多个方法 |
创建方法
1 | public static int stuAge(int a){ |
public static:修饰符
- 可选项,不是必须的
int:返回值类型
- 返回值类型可以是 Java 任意一种类型,包括基本数据类型和所有的引用数据类型
- 也可能一个方法执行结束之后不返回任何数据,此时应使用 void 关键字
- 返回值类型不是 void 的时候,表示这个方法执行结束之后必须返回一个具体的值
- return 值; //值的数据类型必须和方法的返回值一致,否则编译报错
eg. 拥有返回值类型的方法,定义方法计算两个 int 类型数据的商1
2
3
4
5
6public static int divide(int a,int b){
return a / b;
//已经执行 return 语句即结束当前方法
//System.out.println("Wihieree");
//编译报错,因为永远不会执行 sout
}
当返回值为空的时候使用 return; 语句是为了结束当前方法
stuAge:方法名
- 合法的标识符
- 见名知意
- 首字母要求小写,后面每个单词首字母大写
- stuAge stuName maxNumFuntion
a:形参(形式参数)
- 可选项,不是必须
- 形参是局部变量
- 多个形参之间用 “逗号” 隔开,要求类型对应相同,类型不同的时候要求能够进行相应的自动类型转换
- int a,int b,int c
- 形参中起决定性作用的是形参的数据类型,形参的名字就是局部变量的名字
int a:参数列表
- 方法再调用的时候,实际给这个方法传递的真实数据被称为:实际参数,简称实参
- 实参列表和形参列表必须满足
- 数量相同
- 类型对应相同
1
2
3
4
5
6
7//定义一个 sum 方法
public static int sum(int a,int b){
//int a,int b 是形参列表
}
//方法调用
//sum("abc","def"); //编译报错
sum(10,20);
eg. 定义一个 max() 方法,接受 num1 和 num2 两个参数并返回两者之间的最大值1
2
3
4
5
6
7
8
9public static int maxFunt(int num1, int num2) {
int max;
if (num1 > num2) {
max = num1;
}else {
max = num2;
}
return max;
}
方法调用
方法只定义不去调用时不会执行的,只有在调用的时候才会执行
语法规则:1
2<方法的修饰符列表当中有 static >
类名.方法名(实参列表);这是一条 java 语句,表示调用某个类的某个方法,传递这样的实参
eg.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44//public 表示公开的
//class 表示定义类
// MethodTest03 是一个类名
public class MethodTest03 {
//表示定义一个公开的类 MethodTest03,由于是公开的类,所以源文件名必须为 MethodTest03
//类体
//类体中不能直接编写 java 语句,除声明变量之外
//方法出现在类体当中
//方法
//public 表示公开的
//static 表示静态的
//void 表示方法执行结束之后不返回任何数据
//main 是方法名:主方法
//(String[] args):形式参数列表,其中String[]是一种引用数据类型,args 是一个局部变量的变量名
//以下只有 args 这个局部变量的变量名是随意的
//主方法就需要这样固定编写,这是程序的入口(SUN 规定的,必须这样写)
public static void main(String[] args){
//这里的程序是一定会执行的
//main 方法是 JVM 负责调用的,是一个入口位置
//从这里作为起点开始执行程序
//在这里调用其它方法
//调用 MethodTest03 的 sum 方法,传递两个实参
MethodTest03.sum(10,20); //实参
//一个方法可以被重复使用,重复调用
int a = 300;
MethodTest03.sum(a,500);
}
//自定义方法:不是程序的入口
//方法作用:计算两个 int 类型数据的和,不要求返回结果,但是要求将结果直接输出到控制台
//修饰符列表:public static
//返回值类型:void
//方法名:sum
//形式参数列表:(int x,int y)
//方法体:主要任务是求和之后输出计算结果
public static void sum(int i,int j){//形参
System.out.println(i + " + " + j + " = " + (i + j));
}
}
参数的值传递
在调用函数时参数是必须被传递的,并且他们的次序必须和他们创建时的参数次序是一样的,参数可以通过值或引用来传递
eg. 通过值来传递参数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class CanShuTest01 {
public static void main(String[] args) {
int i = 10;
add(i);
System.out.println("main -->> " + i); // 10 这里的值是 main 方法里的 i 的值
}
public static void add(int i) {
i++;
System.out.println("add -->> " + i); // 11
}
}
eg. 通过值来传递参数,当传递的是内存地址的时候1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public class CanShuTest02 {
public static void main(String[] args) {
User1 u = new User1(20);
add(u);
System.out.println("main -->> " + u.age);//21
//因为这里的 u 指向的 User1 对象的 age 值在 add 方法
//里修改成了 21
}
//User1 u 形参
public static void add(User1 u) {
u.age++;
System.out.println("add -->> " + u.age); //21
}
}
class User1{
//实例变量
int age;
//构造方法
public User1(int i) {
age = i;
}
}
方法重载 overload
当一个方法有两个或者更多的方法,他们的名字一样但是参数不同时,就叫做方法的重载
它与覆盖是不同的,覆盖是指方法具有相同的名字,类型以及参数的个数
方法重载的优点:
- 程序员调用方法的时候,比较方便,虽然调用的是不同的方法,但是就感觉在调用同一个方法,不需要记忆更多的方法名
方法重载的条件:
- 在同一个类当中
- 方法名相同
- 参数列表不同:数量、顺序、类型不同
- 方法重载和方法名 + 参数列表有关系
- 方法重载和返回值类型、修饰符列表无关
eg. 定义一个计算两个 int 类型、long 类型、double 类型 数据的和的方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class OverloadTest01 {
public static void main(String[] args){
System.out.println(sum(1,2)); //3
System.out.println(sum(1.3,2.5)); //3.8
System.out.println(sum(10L,20L)); //30
}
public static int sum(int a,int b){
return a + b;
}
public static long sum(long a,long b){
return a + b;
}
public static double sum(double a,double b){
return a + b;
}
}
方法递归
方法递归即为方法自身调用自身1
2
3a(){
a();
}
递归是很耗费栈内存的,递归算法可以不用的时候尽量别用
递归必须有结束条件,没有结束条件一定会发生栈溢出错误1
2
3
4
5
6
7
8
9
10
11
12
13public class RecursionTest01 {
//主方法
public static void main(String[] args){
//调用 doSome 方法
doSome();
}
// doSome 会被重复调用
public static void doSome(){
System.out.println("doSome begin");
doSome();//这行代码不结束,下一行程序是无法运行的
System.out.println("doSome over");
}
}
递归即使有了结束条件,即使结束条件是正确的,也可能会发生栈内存溢出错误,因为递归太深了
主要应用为目录拷贝
eg. 使用递归计算 1~N 的求和1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class RecursionTest03 {
public static void main(String[] args){
//1~4 的和
int n = 4;
int retValue = sum(n);
System.out.println(retValue);
}
public static int sum(int n){
// 4 + 3 + 2 + 1
if (n == 1){
return 1;
}
return n + sum(n-1);
}
}
构造方法(构造函数 / 构造器 / Constructor)
构造方法的作用:构造方法存在的意义是通过构造方法的调用,可以创建对象
当一个对象被创建时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值
成员变量之实例变量,属于对象级别的变量,这种变量必须先有对象才能有实例变量
实例变量没有手动赋值的时候,系统默认赋值,在构造方法执行过程中完成的赋值1
2
3
4
5
6
7
8
9
10构造方法语法结构:
[修饰符列表] 构造方法名(形式参数列表){
构造方法体;
}
//虽然构造方法语法没有返回值类型,但是构造方法执行之后有返回值
普通方法的语法结构:
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}
对于构造方法来说,”返回值类型”不需要指定,并且也不能写 void, 只要写上 void,那么这个方法就是普通方法
通常会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来创建一个完整的对象
当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法被称为缺省构造器
当一个类显示的将构造方法定义出来了,那么系统则不再默认为这个类提供缺省构造器;建议开发中手动的为当前类提供无参数构造方法
构造方法支持重载机制
在 Java 类和对象的封装中进行补充说明
static 关键字
1 | 1. static 译为 静态的 |
方法定义为静态的情况:1
2
31. 方法描述的是动作,当所有的对象执行这个动作的时候,最终产生影响是一样的,那么这个动作已经不再属于某一对象动作了,可以将这个动作提升为类级别的动作,模板级别的动作
2. 静态方法中无法直接访问实例变量和实例方法
3. 大多数方法都定义为实例方法,一般一个行为或者一个动作在发生的时候,都需要对象的参与,但是也有例外,例如:大多数"工具类"中的方法都是静态方法,因为工具类就是方便编程,为了方便方法的调用,自然不需要 new 对象是最好的